﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using Gemli.Data.Providers;
using System.Collections;
using System.Collections.ObjectModel;
using Gemli.Data.Linq;

namespace Gemli.Data
{
    public partial class DataModelQuery<TModel> : ExpressionVisitor, IOrderedQueryable<TModel>
    {

        IEnumerator<TModel> IEnumerable<TModel>.GetEnumerator()
        {
            var qthis = (IQueryable<TModel>)this;
            var qprovider = (IQueryProvider)this.Provider;
            return ((IEnumerable<TModel>)qprovider.Execute(qthis.Expression)).GetEnumerator();
        }

        System.Collections.IEnumerator IEnumerable.GetEnumerator()
        {
            return ((IEnumerable<TModel>)this).GetEnumerator();
        }

        /// <summary>
        /// The type that is being queried against, 
        /// i.e. <typeparamref name="TModel"/>.
        /// </summary>
        Type IQueryable.ElementType
        {
            get { return typeof(TModel); }
        }

        private System.Linq.Expressions.Expression _Expression { get; set; }
        /// <summary>
        /// Gets the expression tree that is associated with this instance of <see cref="IQueryable"/>.
        /// </summary>
        System.Linq.Expressions.Expression IQueryable.Expression
        {
            get { return this.Expression; }
        }

        protected internal virtual System.Linq.Expressions.Expression Expression
        {
            get { return _Expression ?? (_Expression = System.Linq.Expressions.Expression.Constant(this)); }
            set
            {
                _Expression = value;
            }
        }

        IQueryProvider IQueryable.Provider
        {
            get { return this.Provider ?? ProviderDefaults.AppProvider; }
        }

    }

}
